use std::ops::Bound;

use prost_types::Timestamp;
use sqlx::postgres::types::PgRange;

use crate::error::Error;

mod query;
mod reservation;
mod status;

// 将PgRange的Bound中的内容提取出来
struct NativeBound<T> {
    start: Option<T>,
    end: Option<T>,
}

impl<T> From<PgRange<T>> for NativeBound<T> {
    fn from(range: PgRange<T>) -> Self {
        let f = |b: Bound<T>| match b {
            Bound::Included(v) => Some(v),
            Bound::Excluded(v) => Some(v),
            Bound::Unbounded => None,
        };
        let start = f(range.start);
        let end = f(range.end);

        Self { start, end }
    }
}

// 传入的查询struct可以实现参数校验的逻辑
pub trait Validator {
    fn validate(&self) -> Result<(), Error>;
}

pub fn validate_range(start: Option<&Timestamp>, end: Option<&Timestamp>) -> Result<(), Error> {
    if start.is_none() || end.is_none() {
        return Err(Error::InvalidTime);
    }

    // 转为DateTime进行比较 TODO: as_ref
    /* let start = convert_to_utc_time(self.start.as_ref().unwrap().clone());
    let end = convert_to_utc_time(self.end.as_ref().unwrap().clone()); */

    // 用timestamp类型直接比较
    let start = start.as_ref().unwrap();
    let end = end.as_ref().unwrap();
    if start.seconds >= end.seconds {
        return Err(Error::InvalidTime);
    }

    Ok(())
}
